home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $RCSfile: Uptime.c,v $
- ** $Filename: Uptime.c $
- ** $Revision: 1.0 $
- ** $Date: $
- **
- ** Modified by Etienne Vogt from the SysInfo.library example by Petri Nordlund
- ** This file is public domain.
- */
-
- /*
- * This is a fairly complete uptime-program, based on the example provided
- * with the original Executive-based SysInfo.library, which has been modified
- * for use with Sysmon.
- * It supports multiuser.library support to show the number of users currently
- * logged in.
- */
-
- #include <exec/memory.h>
- #include <exec/execbase.h>
- #include <dos/datetime.h>
- #include <devices/timer.h>
- #define __USE_SYSBASE
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/timer.h>
- #include <proto/multiuser.h>
- #include <libraries/multiuser.h>
- #include "SysInfo.h"
- #include "SysInfo_protos.h"
- #include "SysInfo_pragmas.h"
- #include "/sysmon.h"
- #include "/sysmon_protos.h"
- #include "/sysmon_pragmas.h"
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
-
-
- /* PROTOTYPES */
- int main(int argc, char **argv);
- static void cleanexit(ULONG rc);
- static void AddUser(ULONG user, UWORD *uids, ULONG *nusers);
- static ULONG CountTasks(void);
- static void GetTime(void);
- static void Users(void);
- static void LoadAverages(void);
- static void Uptime(void);
- static ULONG EClockDivide(struct EClockVal *numerator, ULONG denominator);
-
-
- /* VARIABLES */
- struct muBase *muBase = NULL;
- struct SysInfo *si = NULL;
- struct Library *SysInfoBase = NULL;
- extern struct ExecBase *SysBase;
- extern struct DosLibrary *DOSBase;
- struct SysmonBase *SysmonBase = NULL;
- struct Device *TimerBase = NULL;
- struct timerequest myTimeReq;
-
- static UBYTE version[] = "$VER: Uptime 1.0 (3.8.2001)";
-
- int main(int argc, char **argv)
- {
- if ((SysmonBase = (struct SysmonBase *)OpenLibrary("sysmon.library",1)) == NULL)
- { puts("Can't open sysmon.library.");
- cleanexit(RETURN_FAIL);
- }
-
- if (!(SysInfoBase = OpenLibrary(SYSINFONAME, SYSINFOVERSION)))
- { puts("Can't open SysInfo.library.");
- cleanexit(RETURN_FAIL);
- }
-
- /* Initialize SysInfo.library, this will make the connection to the
- * server-process and allocate the SysInfo-structure. */
- if (!(si = InitSysInfo()))
- { puts("Can't initialize SysInfo.");
- cleanexit(RETURN_FAIL);
- }
-
- if (OpenDevice(TIMERNAME, UNIT_ECLOCK, (struct IORequest *)&myTimeReq, 0L))
- { printf("Can't open %s\n", TIMERNAME);
- cleanexit(RETURN_FAIL);
- }
- else TimerBase = myTimeReq.tr_node.io_Device;
-
- /* If this fails, we'll just output "1 user" */
- muBase = (struct muBase *) OpenLibrary(MULTIUSERNAME, MULTIUSERVERSION);
-
- GetTime();
- printf(", ");
- Uptime();
- printf(", ");
- Users();
- printf(", ");
- LoadAverages();
- printf("\n");
-
- cleanexit(RETURN_OK);
- }
-
-
- /*
- * Exit. Free everything.
- */
- static void cleanexit(ULONG rc)
- {
- if (muBase) CloseLibrary((struct Library *)muBase);
- if (TimerBase) CloseDevice((struct IORequest *)&myTimeReq);
-
- /* Free SysInfo.library */
- if (si) FreeSysInfo(si);
- if (SysInfoBase) CloseLibrary(SysInfoBase);
- if (SysmonBase) CloseLibrary((struct Library *)SysmonBase);
- exit(rc);
- }
-
-
- /*
- * Print system time
- */
- static void GetTime(void)
- {
- struct DateTime dtime;
- char timestr[LEN_DATSTRING+1];
-
- DateStamp(&dtime.dat_Stamp);
-
- dtime.dat_Format = FORMAT_DOS;
- dtime.dat_Flags = 0;
- dtime.dat_StrDay = NULL;
- dtime.dat_StrDate = NULL;
- dtime.dat_StrTime = timestr;
-
- DateToStr(&dtime);
-
- printf(timestr);
- }
-
-
- /*
- * Print number of users (from Multiuser if available)
- */
- static void Users(void)
- {
- ULONG nusers = 1;
-
- if(muBase)
- { ULONG numtasks;
- UWORD *uids;
-
- smLockTaskTable(LTTF_READ);
-
- /* Count the number of tasks currently in system */
- numtasks = CountTasks();
-
- /* Allocate memory for each task */
- if (uids=AllocVec(numtasks*sizeof(UWORD),MEMF_CLEAR|MEMF_PUBLIC))
- { struct TaskInfo *tinfo = NULL;
-
- /* Find out how many different uids there are */
-
- nusers = 0;
- while (tinfo = smNextTaskInfo(tinfo)) AddUser(muGetTaskOwner(tinfo->ti_Task), uids, &nusers);
- FreeVec(uids);
- }
-
- smUnLockTaskTable(LTTF_READ);
- }
-
- if ((nusers>1) || (nusers==0)) printf("%d users", nusers);
- else printf("%d user",nusers);
- }
-
-
- static void AddUser(ULONG user, UWORD *uids, ULONG *nusers)
- {
- UWORD uid;
- BOOL found = FALSE;
- ULONG i;
-
- if (user)
- { uid = user>>16;
- for (i=0; !found && (i<*nusers); i++) found = (uids[i] == uid);
- if (!found) uids[(*nusers)++] = uid;
- }
- }
-
- static ULONG CountTasks(void)
- { ULONG i = 0;
- struct TaskInfo *tinfo = NULL;
-
- while (tinfo = smNextTaskInfo(tinfo)) i++;
-
- return i;
- }
-
-
- /*
- * Print uptime from timer.device EClock.
- */
- static void Uptime(void)
- { struct EClockVal UpTime;
- ULONG EClockRate;
- ULONG days, hrs, mins;
-
- EClockRate = ReadEClock(&UpTime);
-
- mins = EClockDivide(&UpTime, 60*EClockRate);
- days = mins / (24*60);
- mins %= 24*60;
- hrs = mins / 60;
- mins %= 60;
-
- if (days || hrs || mins) printf("up ");
-
- if (days > 0)
- { if (days > 1) printf("%d days ", days);
- else printf("%d day ", days);
- }
-
- if (hrs > 0) printf("%d:%02d", hrs, mins);
- else
- { if ((mins > 1) || (mins == 0)) printf("%d mins", mins);
- else printf("%d min", mins);
- }
- }
-
- static ULONG EClockDivide(struct EClockVal *numerator, ULONG denominator)
- { int bits;
- ULONG d1,d2,d3;
-
- d1 = 0x0;
- d2 = numerator->ev_hi;
- d3 = numerator->ev_lo;
-
- for (bits = 0; bits < 64; bits++)
- { /* now left-shift d1,d2,d3 */
- d1 <<= 1;
- if (d2 & 0x80000000) d1 |= 0x1;
- d2 <<= 1;
- if (d3 & 0x80000000) d2 |= 0x1;
- d3 <<= 1;
-
- if (d1 >= denominator)
- { d1 -= denominator;
- d3 |= 0x1;
- }
- }
-
- /* fill in the remainder */
- numerator->ev_lo = d1;
-
- /* return the quotient, or the low part of it, at least */
- return d3;
- }
-
-
- /*
- * Print load averages
- */
- static void LoadAverages(void)
- { struct SI_LoadAverage load; /* This will be filled by GetLoadAverage() */
-
- GetLoadAverage(si, &load); /* Ask SysInfo.library for current load averages */
-
- printf("load:");
-
- switch (si->loadavg_type)
- { case LOADAVG_FIXEDPNT: /* Convert fixed point values to floating point values */
- if (si->loadavg_time1) printf(" %.2f",(float) load.lavg_fixed.load1 / (float) si->fscale);
- else printf(" N/A");
-
- if (si->loadavg_time2) printf(" %.2f",(float) load.lavg_fixed.load2 / (float) si->fscale);
- else printf(" N/A");
-
- if (si->loadavg_time3) printf(" %.2f",(float) load.lavg_fixed.load3 / (float) si->fscale);
- else printf(" N/A");
-
- break;
-
- default: /* Load average type is not supported */
- printf("-");
- }
- }
-